#include "uart.h"

bool UART_CtrlBLED(const char *filename, bool onOff) {
    int32_t fd = open(filename, O_WRONLY);
    if (fd < 0) {
        return false;
    }

    // '1' -> 点亮
    // '0' -> 熄灭
    write(fd, onOff ? "\x1" : "\x0", 1);

    close(fd);
    return true;
}

int32_t UART_InitSerial(const char *file, uint32_t baudrate) {
    int uartFd = open(file, O_RDWR);
    if (uartFd < 0) {
        return -1;
    }

    struct termios myserial;
    // 清空结构体
    memset(&myserial, 0, sizeof(myserial));

    myserial.c_cflag |= (CLOCAL | CREAD);
    // 设置控制模式状态，本地连接，接受使能
    // 清空数据位
    myserial.c_cflag &= ~CSIZE;
    // 无硬件流控制
    myserial.c_cflag &= ~CRTSCTS;
    // 数据位:8
    myserial.c_cflag |= CS8;

    // 1 位停止位
    myserial.c_cflag &= ~CSTOPB;
    // 不要校验
    myserial.c_cflag &= ~PARENB;
    // myserial.c_iflag |= IGNPAR;   //不要校验
    // myserial.c_oflag = 0;  //输入模式
    // myserial.c_lflag = 0;  //不激活终端模式

    switch (baudrate) {
        case 9600:
            cfsetospeed(&myserial, B9600);
            cfsetispeed(&myserial, B9600);
            break;
        case 115200:
            cfsetospeed(&myserial, B115200);
            cfsetispeed(&myserial, B115200);
            break;
        case 19200:
            cfsetospeed(&myserial, B19200);
            cfsetispeed(&myserial, B19200);
            break;
    }

    tcflush(uartFd, TCIFLUSH);
    tcsetattr(uartFd, TCSANOW, &myserial);

    return uartFd;
}

void *UART_GetMQ2(void *arg) {
    if (arg == NULL) {
        return NULL;
    }

    Callback callback = (Callback)arg;

    int32_t fd = UART_InitSerial(COM2, 9600);

    // 烟雾数值
    int32_t smoke = 0;

    // 通信
    while (true) {
        pthread_testcancel();

        // 发送命令
        uint8_t cmd[] = {0xFF, 0x01, 0x86, 0, 0, 0, 0, 0, 0x79};
        write(fd, cmd, sizeof(cmd));

        // 接收数据
        uint8_t buf[9] = {0};
        read(fd, buf, sizeof(cmd));

        // 解析数据
        smoke = buf[2] << 8 | buf[3];

        callback(&smoke);
    }

    close(fd);
    return NULL;
}

void *UART_GetGY39(void *arg) {
    if (arg == NULL) {
        return NULL;
    }

    Callback callback = (Callback)arg;

    int32_t fd = UART_InitSerial(COM4, 9600);
    uint8_t cmd[] = {0xA5, 0x83, 0x28};
    write(fd, cmd, sizeof(cmd));

    GY39 data = {0, 0, 0, 0, 0};

    while (true) {
        pthread_testcancel();
        uint8_t buf[24] = {0};
        read(fd, buf, 24);

        // 光照
        data.gz = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
        data.gz = data.gz / 100;

        // 温度
        data.wd = (buf[13] << 8) | buf[14];
        data.wd = data.wd / 100;

        // 气压
        data.qy = (buf[15] << 24) | (buf[16] << 16) | (buf[17] << 8) | buf[18];
        data.qy = data.qy / 100;

        // 湿度
        data.sd = (buf[19] << 8) | buf[20];
        data.sd = data.sd / 100;

        // 海拔
        data.hb = (buf[21] << 8) | buf[22];
        data.hb = data.hb / 100;

        callback(&data);
    }

    close(fd);
    return NULL;
}
